// main.cpp
#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <fstream>
#include <sstream>
#include <iostream>

// --- 新增：鼠标位置变量 ---
double mouseX = 0.0;
double mouseY = 0.0;
bool mousePressed = false;

// 从文件读取着色器源码
std::string loadShaderSource(const std::string& filePath) {
    std::ifstream file;
    std::stringstream buffer;

    try {
        file.open(filePath);
        if (!file.is_open()) {
            throw std::runtime_error("无法打开文件: " + filePath);
        }
        buffer << file.rdbuf();
        file.close();
    } catch (const std::exception& e) {
        std::cerr << "着色器文件读取错误: " << e.what() << std::endl;
        return "";
    }

    return buffer.str();
}

// 编译着色器（类型 + 文件路径）
unsigned int compileShader(unsigned int type, const std::string& filePath) {
    std::string source = loadShaderSource(filePath);
    if (source.empty()) {
        std::cerr << "着色器源码为空: " << filePath << std::endl;
        return 0;
    }

    const char* src = source.c_str();
    unsigned int shader = glCreateShader(type);
    glShaderSource(shader, 1, &src, nullptr);
    glCompileShader(shader);

    int success;
    char infoLog[512];
    glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
    if (!success) {
        glGetShaderInfoLog(shader, 512, nullptr, infoLog);
        std::cerr << "着色器编译失败 (" << filePath << "):\n" << infoLog << std::endl;
        glDeleteShader(shader);
        return 0;
    }
    return shader;
}

int main() {
    // 初始化 GLFW
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

#ifdef __APPLE__
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif

    // 创建窗口
    GLFWwindow* window = glfwCreateWindow(800, 600, "Shadertoy 移植示例（文件版）", nullptr, nullptr);
    if (!window) {
        std::cerr << "创建窗口失败！" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    // 初始化 GLAD
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
        std::cerr << "初始化 GLAD 失败！" << std::endl;
        return -1;
    }

    // 设置视口
    int width, height;
    glfwGetFramebufferSize(window, &width, &height);
    glViewport(0, 0, width, height);
    glfwSetFramebufferSizeCallback(window, [](GLFWwindow*, int w, int h) {
        glViewport(0, 0, w, h);
    });

    // --- 新增：鼠标移动回调 ---
    glfwSetCursorPosCallback(window, [](GLFWwindow* win, double x, double y) {
        int width, height;
        glfwGetFramebufferSize(win, &width, &height);

        // 转换为像素坐标，Y轴翻转（Shadertoy 使用左下角为原点）
        mouseX = x;
        mouseY = height - y;  // 翻转Y轴
    });

    // --- 新增：鼠标按下/释放回调（可选：用于 iMouse.zw）---
    glfwSetMouseButtonCallback(window, [](GLFWwindow* win, int button, int action, int mods) {
        if (button == GLFW_MOUSE_BUTTON_LEFT) {
            if (action == GLFW_PRESS) {
                mousePressed = true;
                // 可在此记录起始点到 iMouse.zw
            } else if (action == GLFW_RELEASE) {
                mousePressed = false;
            }
        }
    });

    // 从文件加载并编译着色器，相对路径以build目录为起点
    unsigned int vertexShader = compileShader(GL_VERTEX_SHADER, "../shaders/tunnel.vert");
    unsigned int fragmentShader = compileShader(GL_FRAGMENT_SHADER, "../shaders/sea.frag");

    if (!vertexShader || !fragmentShader) {
        std::cerr << "着色器编译失败，程序退出。" << std::endl;
        glfwTerminate();
        return -1;
    }

    // 创建着色器程序
    unsigned int shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    int success;
    char infoLog[512];
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);
        std::cerr << "着色器程序链接失败:\n" << infoLog << std::endl;
    }

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    // 创建全屏四边形 (VAO/VBO/EBO)
    float vertices[] = {
        -1.0f, -1.0f,
         1.0f, -1.0f,
        -1.0f,  1.0f,
         1.0f,  1.0f
    };

    unsigned int indices[] = {
        0, 1, 2,
        1, 3, 2
    };

    unsigned int VBO, VAO, EBO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);

    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    // 获取 uniform 位置
    glUseProgram(shaderProgram);
    int iResolutionLoc = glGetUniformLocation(shaderProgram, "iResolution");
    int iTimeLoc = glGetUniformLocation(shaderProgram, "iTime");
    int iTimeDeltaLoc = glGetUniformLocation(shaderProgram, "iTimeDelta");
    int iFrameLoc = glGetUniformLocation(shaderProgram, "iFrame");

    float lastTime = 0.0f;
    int frameCount = 0;

    // 渲染循环
    while (!glfwWindowShouldClose(window)) {
        float currentTime = static_cast<float>(glfwGetTime());
        float deltaTime = currentTime - lastTime;
        lastTime = currentTime;

        // ESC 退出
        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
            glfwSetWindowShouldClose(window, true);

        // 清屏
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(shaderProgram);

        // 更新 uniform
        int w, h;
        glfwGetFramebufferSize(window, &w, &h);
        glUniform3f(iResolutionLoc, static_cast<float>(w), static_cast<float>(h), 1.0f);
        glUniform1f(iTimeLoc, currentTime);
        glUniform1f(iTimeDeltaLoc, deltaTime);
        glUniform1i(iFrameLoc, frameCount);

        float iMouseData[4] = { static_cast<float>(mouseX), static_cast<float>(mouseY), 0.0f, 0.0f };
        glUniform4fv(glGetUniformLocation(shaderProgram, "iMouse"), 1, iMouseData);

        // 绘制全屏四边形
        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

        glfwSwapBuffers(window);
        glfwPollEvents();
        frameCount++;
    }

    // 清理
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteBuffers(1, &EBO);
    glDeleteProgram(shaderProgram);

    glfwTerminate();
    return 0;
}

